package com.jp.refreshlocalcacheclient.process;

import com.jp.refreshlocalcacheclient.annotation.RefreshLocalCache;
import com.jp.refreshlocalcacheclient.data.CacheMethod;
import com.jp.refreshlocalcacheclient.utils.ApplicationContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Map;


/**
 * @Author: jipeng
 * @Description: 缓存方法收集
 * @Date: Created in 2020/4/29 10:44
 */
@Component
public class CacheMethodCollectionProcess implements InitializingBean {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private ApplicationContext applicationContext;

    @Autowired
    HandleRefreshProcess handleRefreshProcess;

    @Override
    public void afterPropertiesSet() {
        initHandlerMethods();
    }

    private void initHandlerMethods(){
        Map<String, Object> mapBeans = applicationContext.getBeansWithAnnotation(RefreshLocalCache.class);
        for(Object beanObj : mapBeans.values()){

            MethodIntrospector.selectMethods(beanObj.getClass(),new ReflectionUtils.MethodFilter(){
               @Override
               public boolean matches(Method method){
                    RefreshLocalCache refreshLocalCache = AnnotationUtils.findAnnotation(method,RefreshLocalCache.class);

                    if(refreshLocalCache == null ){
                        return false;
                    }

                    String cacheKey = refreshLocalCache.value();
                    if(cacheKey == null){
                        //打印到控制台提示，加了注解，但是没有给关联值
                        logger.error("filter refresh local cache method，it is found that the {} method of class {} does not assign a value to the annotation refreshlocalcache", method.getName(), beanObj.getClass().getName());
                        return false;
                    }

                    registerHandlerMethod(cacheKey,method,beanObj);
                    return true;
               }
            });
        }
    }


    /**
     * 注册处理方法
     * @param key
     * @param method
     * @param obj
     */
    private void registerHandlerMethod(String key,Method method,Object obj){
        handleRefreshProcess.addCacheMethod(new CacheMethod(key,method,obj));
    }
}
